package ar.com.seminario.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import ar.com.seminario.common.service.exception.ServiceException;
import ar.com.seminario.dto.CandidatoDto;
import ar.com.seminario.dto.PerfilDto;
import ar.com.seminario.dto.SolicitudCandidatoDto;
import ar.com.seminario.dto.SolicitudIngresoDto;
import ar.com.seminario.model.Oficina;
import ar.com.seminario.model.Perfil;
import ar.com.seminario.model.SolicitudCandidato;
import ar.com.seminario.service.ICandidatoService;
import ar.com.seminario.service.IOficinaService;
import ar.com.seminario.service.IPerfilService;
import ar.com.seminario.service.ISolicitudCandidatoService;
import ar.com.seminario.service.ISolicitudIngresoService;
import ar.com.seminario.service.SolicitudIngresoService;
import ar.com.seminario.systema.model.Usuario;

/**
 * Controller para el manejo de solicitudes de ingreso.
 * 
 * @author Pablo Lamas
 * 
 */
@Controller
public class SolicitudesController extends GenericController {

	/**
	 * Logger del controller.
	 */
	private static final Logger LOG = LoggerFactory.getLogger(SolicitudesController.class);

	/**
	 * Servicio de acceso a {@link Perfil}.
	 */
	@Autowired
	private IPerfilService perfilService;

	/**
	 * Servicio de acceso a {@link Oficina}.
	 */
	@Autowired
	private IOficinaService oficinaService;

	/**
	 * Servicio de acceso a {@link SolicitudIngresoService}.
	 */
	@Autowired
	private ISolicitudIngresoService solicitudIngresoService;

	/**
	 * Servicio de acceso a {@link SolicitudCandidato}.
	 */
	@Autowired
	private ISolicitudCandidatoService solicitudCandidatoService;

	/**
	 * Despliega la pantalla de crear una solicitud de ingreso.
	 * 
	 */
	@Autowired
	private ICandidatoService candidatoService;
	
	@RequestMapping(value = "/crearSolicitudIngreso", method = RequestMethod.GET)
	public final ModelAndView getPageCrearSolicitudIngreso(ModelMap model, HttpServletRequest request) {

		try {

			this.getStartModel(model, request);
			this.buildModel(model, request);

		} catch (final Exception e) {
			SolicitudesController.LOG.error("Error creando el Dto de datos de la pagina.");
		}

		return (new ModelAndView("crear-solicitud", model));

	}

	/**
	 * Despliega la pantalla de administrar Solicitudes de ingreso.
	 * 
	 */
	@RequestMapping(value = "/administrarSolicitudes", method = RequestMethod.GET)
	public final ModelAndView getPageAdministrarSolicitudes(ModelMap model, HttpServletRequest request) {

		try {

			this.getStartModel(model, request);

			Usuario usuario = (Usuario) request.getSession().getAttribute("usuarioEnSession");
			List<SolicitudIngresoDto> solicitudes = this.solicitudIngresoService.
					getAllSolicitudesByTipoUsuario(usuario.getTipoUsuario()); 
		
			model.put("solicitudes",solicitudes);
			if(solicitudes!=null){
				model.put("solicitudesSize",solicitudes.size());
			}else{
				model.put("solicitudesSize",0);
			}

		} catch (final Exception e) {
			SolicitudesController.LOG.error("Error creando el Dto de datos de la pagina.");
		}

		return (new ModelAndView("administrar-solicitudes", model));
	}

	/**
	 * Despliega la pantalla de consulta de datos de la solicitud de ingreso.
	 * 
	 */
	@RequestMapping(value = "/consultarsolicitud", method = RequestMethod.POST)
	public final ModelAndView getPageConsultarSolicitud(ModelMap model, Long idSolicitud, HttpServletRequest request) {

		try {

			this.getStartModel(model, request);
			model.put("solicitud", this.solicitudIngresoService.getSolicitudDtoPorId(idSolicitud));

		} catch (Exception e) {
			SolicitudesController.LOG.error("Error obteniento la solicitud de ingreso buscada.");
		}
		return (new ModelAndView("consultar-solicitud", model));

	}

	/**
	 * Ejecuta la accion de cerrar la solicitud de ingreso.
	 * 
	 */
	@RequestMapping(value = "/cerrarSolicitud", method = RequestMethod.POST)
	@ResponseBody
	public final String cerrarSolicitudIngreso(ModelMap model, Long idSolicitud, String justificacion) {

		String respuesta = new String("");

		try {

			this.solicitudIngresoService.cerrarSolicitudIngreso(idSolicitud, justificacion);
			respuesta = this.armarRespuesta(true, "La solicitud fue cerrada con exito");

		} catch (ServiceException e) {
			respuesta = this.armarRespuesta(false, "");
		}

		return respuesta;

	}

	/**
	 * Guarda la solicitud de ingreso creada.
	 * 
	 */
	@RequestMapping(value = "/guardarSolicitudIngreso", method = RequestMethod.POST)
	@ResponseBody
	public final String saveSolicitudIngreso(
			@ModelAttribute("SolicitudIngresoDto") SolicitudIngresoDto solicitudIngresoDto, ModelMap model,
			HttpServletResponse response) {

		String respuesta = new String("");

		try {

			this.solicitudIngresoService.saveSolicitudIngreso(solicitudIngresoDto);
			respuesta = this.armarRespuesta(true, "La solicitud fue guardado con exito");

		} catch (ServiceException e) {
			respuesta = this.armarRespuesta(false, "");
		}

		return respuesta;
	}

	/**
	 * Redirecciona a la pantalla de crear busqueda.
	 */
	@RequestMapping(value = "/gestionarSolicitudAprobada", method = RequestMethod.POST)
	public final ModelAndView doGestionarSolicitudAprobada(ModelMap model, Long idSolicitud, HttpServletRequest request) {

		try {

			this.getStartModel(model, request);
			SolicitudIngresoDto  solicitud = this.solicitudIngresoService.getSolicitudDtoPorId(idSolicitud);
			model.put("solicitud",solicitud);

			List<SolicitudCandidatoDto> postulantesAsociados = this.solicitudCandidatoService
					.getPostulantesAsociados(idSolicitud);

		    List<PerfilDto> perfilesCompatibles = perfilService.getPerfilesCompatibles(perfilService.getPerfilById(solicitud.getPerfilId()));
		    List<CandidatoDto> postulantesPosibles =  this.candidatoService.getCandidatosPorPerfiles(perfilesCompatibles);
		    
			model.put("postulantesPosibles", postulantesPosibles);
			model.put("postulantesAsociados", postulantesAsociados);

			model.put("hayPpostulantesPosibles",postulantesPosibles.size());
			model.put("hayPostulantesAsociados", postulantesAsociados.size());

			return (new ModelAndView("crear-busqueda", model));

		} catch (Exception e) {
			e.printStackTrace();
			return (new ModelAndView("administrar-solicitudes", model));
		}
	}

	/**
	 * Despliega la pantalla de aprobacion de datos de la solicitud de ingreso.
	 * 
	 */
	@RequestMapping(value = "/pageAprobarSolicitud", method = RequestMethod.POST)
	public final ModelAndView getPageAprobarSolicitud(ModelMap model, Long idSolicitud, HttpServletRequest request) {

		try {

			this.getStartModel(model, request);
			model.put("solicitud", this.solicitudIngresoService.getSolicitudDtoPorId(idSolicitud));

		} catch (Exception e) {
			SolicitudesController.LOG.error("Error obteniento la solicitud de ingreso buscada.");
		}
		return (new ModelAndView("aprobar-solicitud", model));
	}

	/**
	 * Aprueba la solicitud de ingreso.
	 * 
	 */
	@RequestMapping(value = "/aprobarSolicitudIngreso", method = RequestMethod.POST)
	@ResponseBody
	public final String aprobarSolicitudIngreso(
			@ModelAttribute("SolicitudIngresoDto") SolicitudIngresoDto solicitudIngresoDto, ModelMap model,
			HttpServletResponse response) {

		String respuesta = new String("");

		try {

			this.solicitudIngresoService.aprobarSolicitudIngreso(solicitudIngresoDto.getIdSolicitud());
			respuesta = this.armarRespuesta(true, "La solicitud fue aprobada con exito");

		} catch (ServiceException e) {
			respuesta = this.armarRespuesta(false, "");
		}

		return respuesta;
	}

	/**
	 * Rechaza la solicitud de ingreso.
	 * 
	 */
	@RequestMapping(value = "/rechazarSolicitudIngreso", method = RequestMethod.POST)
	@ResponseBody
	public final String rechazarSolicitudIngreso(Long idSolicitud, String justificacion, ModelMap model,
			HttpServletResponse response) {

		String respuesta = new String("");

		try {

			this.solicitudIngresoService.rechazarSolicitudIngreso(idSolicitud, justificacion);
			respuesta = this.armarRespuesta(true, "La solicitud fue rechazada con exito");

		} catch (ServiceException e) {
			respuesta = this.armarRespuesta(false, "");
		}

		return respuesta;
	}

	/**
	 * Construye el modelo para la pagina.
	 * 
	 * @param model
	 *            modelo a mostrar en pantalla.
	 * @throws Exception
	 *             En caso de error buscando los datos a mostrar en pantalla.
	 */
	private void buildModel(final ModelMap model, HttpServletRequest request) throws Exception {

		model.put("oficinas", this.oficinaService.getAllOficinas());
		model.put("perfiles", this.perfilService.getAllPerfilesDto());
	}

}
